import base64
import logging
import os
import shutil
import sys
import unittest

import compare
import util


__author__  = 'ZL <837806295@qq.com>'
__product__ = 'test'
__version__ = '3.2.0'
__date__    = '2023/04/08'


log = logging.getLogger(__product__)


class TestCase001(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.test_sequence = 0
        cls.work_dir = util.get_test_subdir(__file__, cls.__name__)

    @classmethod
    def tearDownClass(cls):
        del cls.test_sequence
        del cls.work_dir

        util.remove_test_subdir(__file__, cls.__name__)

    def setUp(self):
        self.test_sequence = self.__class__.test_sequence
        self.work_dir = self.__class__.work_dir
        self.test_dir = util.get_subdir(
            self.work_dir,
            ('{:0>%d}' % 3).format(self.test_sequence + 1))

    def tearDown(self):
        del self.test_sequence
        del self.work_dir
        del self.test_dir

        self.__class__.test_sequence += 1

    def test_command(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" -h'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py')
                )
        )

        self.assertTrue(util.run(cmd))

class TestCase002(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.test_sequence = 0
        cls.work_dir = util.get_test_subdir(__file__, cls.__name__)

    @classmethod
    def tearDownClass(cls):
        del cls.test_sequence
        del cls.work_dir

        util.remove_test_subdir(__file__, cls.__name__)

    def setUp(self):
        self.test_sequence = self.__class__.test_sequence
        self.work_dir = self.__class__.work_dir
        self.test_dir = util.get_subdir(
            self.work_dir,
            ('{:0>%d}' % 3).format(self.test_sequence + 1))

    def tearDown(self):
        del self.test_sequence
        del self.work_dir
        del self.test_dir

        self.__class__.test_sequence += 1

    def test_subcommand_local(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" local -h'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py')
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_local2(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" local "%s" "%s" -e -m 3 -L local2 -l debug'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    util.get_test_subdir(__file__,
                                         ['data', 'dir', 'root']),
                    util.get_test_subdir(__file__,
                                         ['data', 'dir', 'root2'])
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_local3(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" local "%s" "%s" -e -m 5 -c -L local3 -l debug'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    util.get_test_subdir(__file__,
                                         ['data', 'dir', 'root']),
                    util.get_test_subdir(__file__,
                                         ['data', 'dir', 'root2'])
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_local4(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" local "%s" "%s" -L local4'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    util.get_test_subdir(__file__,
                                         ['data', 'dir', 'root']),
                    util.get_test_subdir(__file__,
                                         ['data', 'dir', 'root2'])
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_local5(self):
        if not sys.executable:
            return

        shutil.copytree(
            util.get_test_subdir(__file__, ['data', 'dir', 'root']),
            os.path.join(self.test_dir, 'root'))

        shutil.copytree(
            util.get_test_subdir(__file__, ['data', 'dir', 'root2']),
            os.path.join(self.test_dir, 'root2'))

        cmd = (
            '"%s" "%s" local "%s" "%s" -L local5 -a -d -g'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    os.path.join(self.test_dir, 'root'),
                    os.path.join(self.test_dir, 'root2')
                )
        )

        self.assertTrue(util.run(cmd))

        add = []
        delete = []
        change = []
        compare.compare_dirs2(
            os.path.join(self.test_dir, 'root'),
            util.get_test_subdir(__file__, ['data', 'dir', 'root2']),
            True,
            False,
            3*1024*1024,
            add,
            delete,
            change)

        self.assertFalse(add)
        self.assertFalse(delete)
        self.assertFalse(change)

    def test_subcommand_local6(self):
        if not sys.executable:
            return

        shutil.copytree(
            util.get_test_subdir(__file__, ['data', 'dir', 'root']),
            os.path.join(self.test_dir, 'root'))

        shutil.copytree(
            util.get_test_subdir(__file__, ['data', 'dir', 'root2']),
            os.path.join(self.test_dir, 'root2'))

        cmd = (
            '"%s" "%s" local "%s" "%s" -L local6 -a -d -g -c'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    os.path.join(self.test_dir, 'root'),
                    os.path.join(self.test_dir, 'root2')
                )
        )

        self.assertTrue(util.run(cmd))

        add = []
        delete = []
        change = []
        compare.compare_dirs2(
            os.path.join(self.test_dir, 'root'),
            util.get_test_subdir(__file__, ['data', 'dir', 'root2']),
            True,
            False,
            3*1024*1024,
            add,
            delete,
            change)

        self.assertFalse(add)
        self.assertFalse(delete)
        self.assertFalse(change)

    def test_subcommand_local7(self):
        if not sys.executable:
            return

        shutil.copytree(
            util.get_test_subdir(__file__, ['data', 'dir', 'root']),
            os.path.join(self.test_dir, 'root'))

        shutil.copytree(
            util.get_test_subdir(__file__, ['data', 'dir', 'root2']),
            os.path.join(self.test_dir, 'root2'))

        cmd = (
            '"%s" "%s" local "%s" "%s" -L local7 -a -d'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    os.path.join(self.test_dir, 'root'),
                    os.path.join(self.test_dir, 'root2')
                )
        )

        self.assertTrue(util.run(cmd))

        add = []
        delete = []
        change = []
        compare.compare_dirs2(
            os.path.join(self.test_dir, 'root'),
            util.get_test_subdir(__file__, ['data', 'dir', 'root3']),
            True,
            False,
            3*1024*1024,
            add,
            delete,
            change)

        self.assertFalse(add)
        self.assertFalse(delete)
        self.assertFalse(change)

    def test_subcommand_local8(self):
        if not sys.executable:
            return

        shutil.copytree(
            util.get_test_subdir(__file__, ['data', 'dir', 'root']),
            os.path.join(self.test_dir, 'root'))

        shutil.copytree(
            util.get_test_subdir(__file__, ['data', 'dir', 'root2']),
            os.path.join(self.test_dir, 'root2'))

        cmd = (
            '"%s" "%s" local "%s" "%s" -L local8 -a -c'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    os.path.join(self.test_dir, 'root'),
                    os.path.join(self.test_dir, 'root2')
                )
        )

        self.assertTrue(util.run(cmd))

        add = []
        delete = []
        change = []
        compare.compare_dirs2(
            os.path.join(self.test_dir, 'root'),
            util.get_test_subdir(__file__, ['data', 'dir', 'root4']),
            True,
            False,
            3*1024*1024,
            add,
            delete,
            change)

        self.assertFalse(add)
        self.assertFalse(delete)
        self.assertFalse(change)

    def test_subcommand_local9(self):
        if not sys.executable:
            return

        shutil.copytree(
            util.get_test_subdir(__file__, ['data', 'dir', 'root']),
            os.path.join(self.test_dir, 'root'))

        shutil.copytree(
            util.get_test_subdir(__file__, ['data', 'dir', 'root2']),
            os.path.join(self.test_dir, 'root2'))

        cmd = (
            '"%s" "%s" local "%s" "%s" -L local9 -a -g'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    os.path.join(self.test_dir, 'root'),
                    os.path.join(self.test_dir, 'root2')
                )
        )

        self.assertTrue(util.run(cmd))

        add = []
        delete = []
        change = []
        compare.compare_dirs2(
            os.path.join(self.test_dir, 'root'),
            util.get_test_subdir(__file__, ['data', 'dir', 'root5']),
            True,
            False,
            3*1024*1024,
            add,
            delete,
            change)

        self.assertFalse(add)
        self.assertFalse(delete)
        self.assertFalse(change)

class TestCase003(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.test_sequence = 0
        cls.work_dir = util.get_test_subdir(__file__, cls.__name__)

    @classmethod
    def tearDownClass(cls):
        del cls.test_sequence
        del cls.work_dir

        util.remove_test_subdir(__file__, cls.__name__)

    def setUp(self):
        self.test_sequence = self.__class__.test_sequence
        self.work_dir = self.__class__.work_dir
        self.test_dir = util.get_subdir(
            self.work_dir,
            ('{:0>%d}' % 3).format(self.test_sequence + 1))

    def tearDown(self):
        del self.test_sequence
        del self.work_dir
        del self.test_dir

        self.__class__.test_sequence += 1

    def test_subcommand_export(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" export -h'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py')
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_export2(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" export -L export2 -i -p -n root "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    util.get_test_subdir(__file__, ['data', 'dir', 'root']),
                    self.test_dir
                )
        )

        self.assertTrue(util.run(cmd))
        self.assertTrue(
            os.path.isfile(
                os.path.join(self.test_dir, 'root.description')))

    def test_subcommand_export3(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" export -L export3 -p -n root2 "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    util.get_test_subdir(__file__, ['data', 'dir', 'root2']),
                    self.test_dir
                )
        )

        self.assertTrue(util.run(cmd))
        self.assertTrue(
            os.path.isfile(
                os.path.join(self.test_dir, 'root2.description')))

    def test_subcommand_export4(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" export -L export4 -i -n root3 "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    util.get_test_subdir(__file__, ['data', 'dir', 'root3']),
                    self.test_dir
                )
        )

        self.assertTrue(util.run(cmd))
        self.assertTrue(
            os.path.isfile(
                os.path.join(self.test_dir, 'root3.description')))

    def test_subcommand_export5(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" export -L export5 -n root4 "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    util.get_test_subdir(__file__, ['data', 'dir', 'root4']),
                    self.test_dir
                )
        )

        self.assertTrue(util.run(cmd))
        self.assertTrue(
            os.path.isfile(
                os.path.join(self.test_dir, 'root4.description')))

    def test_subcommand_export6(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" export -L export6 -d -f "%s" "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'difference']),
                        'root_vs_root2.difference'),
                    util.get_test_subdir(__file__, ['data', 'dir', 'root2']),
                    self.test_dir
                )
        )

        self.assertTrue(util.run(cmd))

class TestCase004(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.test_sequence = 0
        cls.work_dir = util.get_test_subdir(__file__, cls.__name__)

    @classmethod
    def tearDownClass(cls):
        del cls.test_sequence
        del cls.work_dir

        util.remove_test_subdir(__file__, cls.__name__)

    def setUp(self):
        self.test_sequence = self.__class__.test_sequence
        self.work_dir = self.__class__.work_dir
        self.test_dir = util.get_subdir(
            self.work_dir,
            ('{:0>%d}' % 3).format(self.test_sequence + 1))

    def tearDown(self):
        del self.test_sequence
        del self.work_dir
        del self.test_dir

        self.__class__.test_sequence += 1

    def test_subcommand_remote(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" remote -h'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py')
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_remote2(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" remote -L remote2 "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    util.get_test_subdir(__file__, ['data', 'dir', 'root']),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'description']),
                        'root2.description')
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_remote3(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" remote -L remote3 -e -c -m 6 "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    util.get_test_subdir(__file__, ['data', 'dir', 'root']),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'description']),
                        'root2.description')
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_remote4(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" remote -L remote4 -e "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    util.get_test_subdir(__file__, ['data', 'dir', 'root']),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'description']),
                        'root2.description')
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_remote5(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" remote -L remote5 -c "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    util.get_test_subdir(__file__, ['data', 'dir', 'root']),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'description']),
                        'root2.description')
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_remote6(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" remote -L remote6 -m 9 "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    util.get_test_subdir(__file__, ['data', 'dir', 'root']),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'description']),
                        'root2.description')
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_remote7(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" remote -L remote7 -f -n root_vs_root2 -o "%s" "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    self.test_dir,
                    util.get_test_subdir(__file__, ['data', 'dir', 'root']),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'description']),
                        'root2.description')
                )
        )

        self.assertTrue(util.run(cmd))
        self.assertTrue(
            os.path.isfile(
                os.path.join(self.test_dir, 'root_vs_root2.difference')))

class TestCase005(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.test_sequence = 0
        cls.work_dir = util.get_test_subdir(__file__, cls.__name__)

    @classmethod
    def tearDownClass(cls):
        del cls.test_sequence
        del cls.work_dir

        util.remove_test_subdir(__file__, cls.__name__)

    def setUp(self):
        self.test_sequence = self.__class__.test_sequence
        self.work_dir = self.__class__.work_dir
        self.test_dir = util.get_subdir(
            self.work_dir,
            ('{:0>%d}' % 3).format(self.test_sequence + 1))

    def tearDown(self):
        del self.test_sequence
        del self.work_dir
        del self.test_dir

        self.__class__.test_sequence += 1

    def test_subcommand_import(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" import -h'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py')
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_import2(self):
        if not sys.executable:
            return

        shutil.copytree(
            util.get_test_subdir(__file__, ['data', 'dir', 'root']),
            os.path.join(self.test_dir, 'root'))

        cmd = (
            '"%s" "%s" import -L import2 -a -d -g "%s" "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    os.path.join(self.test_dir, 'root'),
                    util.get_test_subdir(
                        __file__,
                        ['data', 'difference', 'root_vs_root2']),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'difference']),
                        'root_vs_root2.difference')
                )
        )

        self.assertTrue(util.run(cmd))

        add = []
        delete = []
        change = []
        compare.compare_dirs2(
            os.path.join(self.test_dir, 'root'),
            util.get_test_subdir(__file__, ['data', 'dir', 'root2']),
            True,
            False,
            3*1024*1024,
            add,
            delete,
            change)

        self.assertFalse(add)
        self.assertFalse(delete)
        self.assertFalse(change)

class TestCase006(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.test_sequence = 0
        cls.work_dir = util.get_test_subdir(__file__, cls.__name__)

    @classmethod
    def tearDownClass(cls):
        del cls.test_sequence
        del cls.work_dir

        util.remove_test_subdir(__file__, cls.__name__)

    def setUp(self):
        self.test_sequence = self.__class__.test_sequence
        self.work_dir = self.__class__.work_dir
        self.test_dir = util.get_subdir(
            self.work_dir,
            ('{:0>%d}' % 3).format(self.test_sequence + 1))

    def tearDown(self):
        del self.test_sequence
        del self.work_dir
        del self.test_dir

        self.__class__.test_sequence += 1

    def test_subcommand_history(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" history -h'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py')
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_history2(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" history -L history2 "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'description']),
                        'root.description'),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'description']),
                        'root2.description')
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_history3(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" history -L history3 -c -e "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'description']),
                        'root.description'),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'description']),
                        'root2.description')
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_history4(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" history -L history4 -e "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'description']),
                        'root.description'),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'description']),
                        'root2.description')
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_history5(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" history -L history5 -c "%s" "%s"'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'description']),
                        'root.description'),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data', 'description']),
                        'root2.description')
                )
        )

        self.assertTrue(util.run(cmd))

class TestCase101(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.test_sequence = 0
        cls.work_dir = util.get_test_subdir(__file__, cls.__name__)

    @classmethod
    def tearDownClass(cls):
        del cls.test_sequence
        del cls.work_dir

        util.remove_test_subdir(__file__, cls.__name__)

    def setUp(self):
        self.test_sequence = self.__class__.test_sequence
        self.work_dir = self.__class__.work_dir
        self.test_dir = util.get_subdir(
            self.work_dir,
            ('{:0>%d}' % 3).format(self.test_sequence + 1))

    def tearDown(self):
        del self.test_sequence
        del self.work_dir
        del self.test_dir

        self.__class__.test_sequence += 1

    def test_base64(self):
        data = b'a' * (76 * 2)
        log.info('test base64 ... ongoing | data: %s', data)

        data2 = base64.b64encode(data)
        log.info('test base64 ... ongoing | b64encode: %s', data2)

        data2 = base64.standard_b64encode(data)
        log.info('test base64 ... ongoing | standard b64encode: %s', data2)

        data2 = base64.urlsafe_b64encode(data)
        log.info('test base64 ... ongoing | urlsafe b64encode: %s', data2)

        data2 = base64.encodebytes(data)
        log.info('test base64 ... ongoing | encodebytes: %s', data2)


if __name__ == '__main__':
    util.set_log(__file__, '%s_v%s' % (__product__, __version__), 'debug')

    log.info('program version: %s %s', __product__, __version__)
    log.debug('command line: %s', sys.argv)

    unittest.main()
